/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	ActorManager.cpp
*
*	Comments	-	See ActorManager.h
*
**************************************************************************************/
#include "../Include/FactoryActor.h"
#include "../Include/String.h"

namespace Pulse
{
	FactoryActor::FactoryActor( void )
		: m_newActorID( 0 )
	{

	}

	FactoryActor::~FactoryActor( void )
	{

	}

	ActorPtr FactoryActor::NewActor( void )
	{
		ActorPtr pActor = _NewActor();

		pActor->Initialize( PSX_NULL );

		return pActor;
	}

	ActorPtr FactoryActor::NewActor( XMLElementPtr pActorInit )
	{
		ActorPtr pActor = _NewActor();
		
		pActor->Initialize( pActorInit );

		return pActor;
	}

	EErrorCode::Type FactoryActor::RemoveActor( const ActorPtr &pActor )
	{
		PSX_Assert( pActor.GetRefCount() == 1, "Actor ref count should now be 1 by now before it gets deleted." );

		m_availableIDs.PushBack( pActor->GetID() );
		pActor->RemoveAllComponents();

		// Actor gets deleted after the ActorPtr calling this function loses ref count.

		return EErrorCode::OKAY;
	}

	ActorPtr FactoryActor::_NewActor( void )
	{
		// We want to check the queue first if there's any available
		if ( m_availableIDs.IsEmpty() == FALSE )
		{
			ActorPtr pActor = new Actor( m_availableIDs.GetFront() );
			m_availableIDs.PopFront();
			return pActor;
		}
		else
		{
			ActorPtr pActor = new Actor( m_newActorID );
			IncrementID();
			return pActor;
		}
	}

	void FactoryActor::IncrementID( void )
	{
		++m_newActorID;

		if ( m_newActorID == 0 ) // Wrap around check
		{
			PSX_PushError( "We have created too many actors! Can't believe this was even possible!" );
		}
	}

}